package cn.maihe.elg.operation.supports.electronicseal.anne.service.impl;

import cn.maihe.elg.operation.config.AnneSignConfig;
import cn.maihe.elg.operation.config.ElgConfig;
import cn.maihe.elg.operation.config.ZtAccountInfo;
import cn.maihe.elg.operation.model.bo.GuaranteeTemplatePdfParams;
import cn.maihe.elg.operation.model.bo.ReceiveTemplatePdfParams;
import cn.maihe.elg.operation.model.enums.ContractStatus;
import cn.maihe.elg.operation.model.enums.ContractType;
import cn.maihe.elg.operation.repository.entity.*;
import cn.maihe.elg.operation.supports.electronicseal.anne.AnneServiceName;
import cn.maihe.elg.operation.supports.electronicseal.anne.BaseAnneSignService;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.account.IndividualRealNameSyncRequestBody;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.contract.TemplateContractCreateRequest;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.contract.TemplateContractCreateRequestBody;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.contract.TemplateContractCreateResponse;
import cn.maihe.elg.operation.supports.electronicseal.anne.bean.annesign.contract.vo.TemplateContractSignerReplaceVo;
import cn.maihe.elg.operation.utils.CurrencyUpperUtil;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.IdGenerate;
import cn.maihe.elg.operation.utils.StringUtil;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description 项目申请保函委托书服务
 * @Author WJH
 * @Date 2021/08/13
 */
@Slf4j
@Service
public class ContractCreateService extends BaseAnneSignService<TemplateContractCreateRequest, TemplateContractCreateResponse> {


    @Resource
    private IndividualRealNameSyncService individualRealNameSyncService;
    @Resource
    private ZtAccountInfo ztAccountInfo;

    public ContractCreateService(AnneSignConfig anneSignConfig, ElgConfig elgConfig) {
        super(anneSignConfig, elgConfig);
    }

    @Override
    protected AnneServiceName serviceName() {
        return AnneServiceName.contract_create;
    }


    /**
     * 开立保函申请委托书
     *
     * @param orderInfo 投标申请订单信息
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public Long createGuaranteeDelegateProtocol(AcceptOrderInfoDO orderInfo) {
        Long bidCustomerId = orderInfo.getBidCustomerId();

        BidCustomerDO bidCustomer = MybatisDaoImpl.run().selectById(BidCustomerDO.class, bidCustomerId);
        ProjectInfoDO projectInfo = MybatisDaoImpl.run().selectById(ProjectInfoDO.class, orderInfo.getProjectId());

        String serialNo = IdGenerate.genContractNo();
        TemplateContractCreateRequest request = this.buildBaseReq();

        TemplateContractCreateRequestBody body = new TemplateContractCreateRequestBody();
        body.setName(applyTemplateInfo.getTemplateContractName());
//        结束时间非必填暂不送
//        String endDate = DateUtil.formateDate(projectInfo.getBidOpenTime(), "yyyy-MM-dd HH:mm:ss");
//        body.setLifeEndDate(endDate);
//        body.setSignEndDate(endDate);
        body.setTemplateContractId(applyTemplateInfo.getTemplateContractId());
        body.setThirdContractId(ContractType.SQ.name() + "-" + serialNo);
        body.setSendSms(false);
        body.setTextSize(12F);

        //模板合同替换签署人列表
        body.setTemplateContractSignerReplaceVoList(Lists.newArrayList(
                new TemplateContractSignerReplaceVo(applyTemplateInfo.getSignerCompanyA(), bidCustomer.getLegalPersonName(), bidCustomer.getLegalPersonTel(), bidCustomer.getBidderName())
        ));

        //委托申请书
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("tenderName", projectInfo.getTenderer());
        data.put("bidderName", bidCustomer.getBidderName());
        data.put("projectName", projectInfo.getProjectName());
        String sealDate = DateUtil.getCurrentDate("yyyy-MM-dd");
        data.put("year", sealDate.split("-")[0]);
        data.put("month", sealDate.split("-")[1]);
        data.put("day", sealDate.split("-")[2]);


        Map<Long, Map<String, Object>> templateContractFormDataMap = Maps.newHashMap();
        templateContractFormDataMap.put(applyTemplateInfo.getContractDocumentId(), data);
        body.setTemplateContractFormDataMap(templateContractFormDataMap);

        request.setBody(body);

        TemplateContractCreateResponse response = this.doPost(request);
        Long channelContractId = response.getBody().getContractId();
        AcceptOrderContract acceptOrderContract = AcceptOrderContract.builder()
                .id(IdGenerate.getId()).acceptOrderNo(orderInfo.getAcceptOrderNo())
                .contractName(applyTemplateInfo.getTemplateContractName()).contractType(ContractType.SQ.name()).contractStatus(ContractStatus.CREATED.name())
                .startDate(Date.from(Instant.now())).endDate(projectInfo.getBidOpenTime())
                .localContractId(body.getThirdContractId()).channelContractId(String.valueOf(channelContractId))
                .build();
        MybatisDaoImpl.run().insert(acceptOrderContract);

        return channelContractId;
    }


    /**
     * 担保保函书 创建
     *
     * @param orderInfo 投标申请订单信息
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public AcceptOrderContract createGuaranteeContract(ApplyOrderInfoDO orderInfo) {
        Long bidCustomerId = orderInfo.getBidCustomerId();

        BidCustomerDO bidCustomer = MybatisDaoImpl.run().selectById(BidCustomerDO.class, bidCustomerId);
        ProjectInfoDO projectInfo = MybatisDaoImpl.run().selectById(ProjectInfoDO.class, orderInfo.getProjectId());
        OrganizationDO organization = MybatisDaoImpl.run().selectById(OrganizationDO.class, orderInfo.getOrgId());

        //签署人关联联系人实名认证 ：
        IndividualRealNameSyncRequestBody realNameReqBody = new IndividualRealNameSyncRequestBody();
        realNameReqBody.setIdCard(organization.getLegalIdcard());
        realNameReqBody.setName(organization.getLegalName());
        realNameReqBody.setMobile(organization.getLegalMobile());

//        individualRealNameSyncService.realNameSync(realNameReqBody);


        String guaranteeNo = orderInfo.getGuaranteeNo();
        TemplateContractCreateRequest request = this.buildBaseReq();

        TemplateContractCreateRequestBody body = new TemplateContractCreateRequestBody();
        body.setName(guaranteeProtocol.getTemplateContractName());
        Date bidOpenTime = projectInfo.getBidOpenTime();
        String signEndDate = LocalDateTime.ofInstant(bidOpenTime.toInstant(), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Integer validPeriod = projectInfo.getValidPeriod() == null ? 0 : projectInfo.getValidPeriod();
        // 开标时间+有效期+默认28天  //军采电子保函结束时间暂定为 开标时间+默认28天
        String lifeEndDate = LocalDateTime.ofInstant(bidOpenTime.toInstant(), ZoneId.systemDefault())
                .plusDays(28).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        body.setLifeEndDate(lifeEndDate);
        body.setSignEndDate(signEndDate);
        body.setTemplateContractId(guaranteeProtocol.getTemplateContractId());
        body.setThirdContractId(ContractType.BH.name() + "-" + guaranteeNo);
        body.setSendSms(false);
        body.setTextSize(10F);

        //模板合同替换签署人列表
        body.setTemplateContractSignerReplaceVoList(Lists.newArrayList(
                new TemplateContractSignerReplaceVo(guaranteeProtocol.getSignerCompanyA(), realNameReqBody.getName(), realNameReqBody.getMobile(), organization.getFullName()),
                new TemplateContractSignerReplaceVo(guaranteeProtocol.getSignerLegalA(), realNameReqBody.getName(), realNameReqBody.getMobile(), null)
        ));


        //模板合同表单数据
        GuaranteeTemplatePdfParams pdfParams = new GuaranteeTemplatePdfParams();
        pdfParams.setGuaranteeNo(orderInfo.getGuaranteeNo());
        pdfParams.setTenderName(projectInfo.getTenderer());
        pdfParams.setBidderName(orderInfo.getBidCustomerName());
        pdfParams.setProjectName(orderInfo.getProjectName());
        pdfParams.setBidBond(CurrencyUpperUtil.fenToCurrencyUpper(orderInfo.getBidBond()));
        String[] guaranteeTimeAy = DateUtil.formateDate(orderInfo.getGuaranteeTime(), "yyyy-MM-dd").split("-");
        pdfParams.setYear(guaranteeTimeAy[0]);
        pdfParams.setMonth(guaranteeTimeAy[1]);
        pdfParams.setDay(guaranteeTimeAy[2]);

        //模板合同表单数据
        Map<String, Object> documentFormDataMap = BeanMap.create(pdfParams);

        Map<Long, Map<String, Object>> templateContractFormDataMap = Maps.newHashMap();
        templateContractFormDataMap.put(guaranteeProtocol.getContractDocumentId(), documentFormDataMap);
        body.setTemplateContractFormDataMap(templateContractFormDataMap);

        request.setBody(body);

        TemplateContractCreateResponse response = this.doPost(request);
        Long channelContractId = response.getBody().getContractId();
        AcceptOrderContract acceptOrderContract = AcceptOrderContract.builder()
                .id(IdGenerate.getId()).acceptOrderNo(orderInfo.getAcceptOrderNo())
                .contractName(guaranteeProtocol.getTemplateContractName()).contractType(ContractType.BH.name()).contractStatus(ContractStatus.CREATED.name())
                .startDate(Date.from(Instant.now())).endDate(DateUtil.parseDate(lifeEndDate, "yyyy-MM-dd HH:mm:ss"))
                .localContractId(body.getThirdContractId()).channelContractId(String.valueOf(channelContractId))
                .build();
        MybatisDaoImpl.run().insert(acceptOrderContract);

        return acceptOrderContract;
    }


    /**
     * 到账证明合同 创建
     *
     * @param orderInfo 投标申请订单信息
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public AcceptOrderContract createReceiveContract(ApplyOrderInfoDO orderInfo) {
        Long bidCustomerId = orderInfo.getBidCustomerId();

        BidCustomerDO bidCustomer = MybatisDaoImpl.run().selectById(BidCustomerDO.class, bidCustomerId);
        ProjectInfoDO projectInfo = MybatisDaoImpl.run().selectById(ProjectInfoDO.class, orderInfo.getProjectId());
        OrganizationDO organization = MybatisDaoImpl.run().selectById(OrganizationDO.class, orderInfo.getOrgId());

        //签署人关联联系人实名认证 ：
        IndividualRealNameSyncRequestBody realNameReqBody = new IndividualRealNameSyncRequestBody();
        realNameReqBody.setIdCard(organization.getLegalIdcard());
        realNameReqBody.setName(organization.getLegalName());
        realNameReqBody.setMobile(organization.getLegalMobile());

//        individualRealNameSyncService.realNameSync(realNameReqBody);


        String guaranteeNo = orderInfo.getGuaranteeNo();
        TemplateContractCreateRequest request = this.buildBaseReq();

        TemplateContractCreateRequestBody body = new TemplateContractCreateRequestBody();
        body.setName(receiveProtocol.getTemplateContractName());
        Date bidOpenTime = projectInfo.getBidOpenTime();
        String signEndDate = LocalDateTime.ofInstant(bidOpenTime.toInstant(), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Integer validPeriod = projectInfo.getValidPeriod() == null ? 0 : projectInfo.getValidPeriod();
        // 开标时间+有效期+默认28天  //军采电子保函结束时间暂定为 开标时间+默认28天
        String lifeEndDate = LocalDateTime.ofInstant(bidOpenTime.toInstant(), ZoneId.systemDefault())
                .plusDays(28).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        body.setLifeEndDate(lifeEndDate);
        body.setSignEndDate(signEndDate);
        body.setTemplateContractId(receiveProtocol.getTemplateContractId());
        body.setThirdContractId(ContractType.DZ.name() + "-" + guaranteeNo);
        body.setSendSms(false);
        body.setTextSize(10F);

        //模板合同替换签署人列表
        body.setTemplateContractSignerReplaceVoList(Lists.newArrayList(
                new TemplateContractSignerReplaceVo(receiveProtocol.getSignerCompanyA(), realNameReqBody.getName(), realNameReqBody.getMobile(), organization.getFullName())
        ));


        //模板合同表单数据

        ReceiveTemplatePdfParams pdfParams = new ReceiveTemplatePdfParams();

        pdfParams.setProjectCode(projectInfo.getProjectCode());
//        pdfParams.setPayeeAccNo(organization.getBankAccount());
        pdfParams.setPayeeAccNo(ztAccountInfo.getAccNo());
        pdfParams.setPayerAccNo(bidCustomer.getBankCardNum());
        String[] signDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")).split("-");
        pdfParams.setSignYear(signDate[0]);
        pdfParams.setSignMonth(signDate[1]);
        pdfParams.setSignDay(signDate[2]);

        pdfParams.setGuaranteeNo(orderInfo.getGuaranteeNo());
        pdfParams.setTenderName(projectInfo.getTenderer());
        pdfParams.setBidderName(orderInfo.getBidCustomerName());
        pdfParams.setProjectName(orderInfo.getProjectName());
        pdfParams.setGuaranteeFee(StringUtil.fen2YuanCurrency(orderInfo.getBidBond()));
        //到账时间取值 出函时间
        String[] receiveDate = DateUtil.formateDate(orderInfo.getGuaranteeTime(), "yyyy-MM-dd").split("-");
        pdfParams.setYear(receiveDate[0]);
        pdfParams.setMonth(receiveDate[1]);
        pdfParams.setDay(receiveDate[2]);

        //模板合同表单数据
        Map<String, Object> documentFormDataMap = BeanMap.create(pdfParams);

        Map<Long, Map<String, Object>> templateContractFormDataMap = Maps.newHashMap();
        templateContractFormDataMap.put(receiveProtocol.getContractDocumentId(), documentFormDataMap);
        body.setTemplateContractFormDataMap(templateContractFormDataMap);

        request.setBody(body);

        TemplateContractCreateResponse response = this.doPost(request);
        Long channelContractId = response.getBody().getContractId();
        AcceptOrderContract acceptOrderContract = AcceptOrderContract.builder()
                .id(IdGenerate.getId()).acceptOrderNo(orderInfo.getAcceptOrderNo())
                .contractName(receiveProtocol.getTemplateContractName()).contractType(ContractType.DZ.name()).contractStatus(ContractStatus.CREATED.name())
                .startDate(Date.from(Instant.now())).endDate(DateUtil.parseDate(lifeEndDate, "yyyy-MM-dd HH:mm:ss"))
                .localContractId(body.getThirdContractId()).channelContractId(String.valueOf(channelContractId))
                .build();
        MybatisDaoImpl.run().insert(acceptOrderContract);

        return acceptOrderContract;
    }



}
